package hu.fic.weddingstorefinder.utils;

import hu.fic.weddingstorefinder.R;
import hu.fic.weddingstorefinder.db.table.ApplicationConf;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.util.Log;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.JsonHttpResponseHandler;

public class UpdateHandler extends AsyncHttpResponseHandler implements JSONProcessorListener {
	private final static String LOG_TAG = "UpdateHandler";
	private UpdateHandlerListener updateHandlerListener;
	private Activity activityForDB;
	private String errorMessage;
	private String updateResultMessage;

	private int updateType;
	private int updateState;
	private long serverLastUpdateTimestamp;
	
	

	public UpdateHandler(Activity activityForDB, UpdateHandlerListener updateHandlerListener) {
		this.activityForDB = activityForDB;
		this.updateHandlerListener = updateHandlerListener;
	}
	
	public void checkForUpdate() {
		this.updateType = Constants.UPDATE_TYPE_CHECK_FOR_UPDATE;
		AsyncHttpClient client = new AsyncHttpClient();
		client.get(Constants.URL_BASE + Constants.URL_SUFFIX_CHECK_FOR_UPDATE, this);
	}
	
	public void update() {
		this.updateType = Constants.UPDATE_TYPE_UPDATE;
		if (Utils.isOnline(activityForDB)) {
			this.updateHandlerListener.updateIsInProgress(activityForDB.getString(R.string.checking_for_update));
			
			this.updateState = Constants.UPDATE_STATE_CHECK_FOR_UPDATE;
			AsyncHttpClient client = new AsyncHttpClient();
			client.get(Constants.URL_BASE + Constants.URL_SUFFIX_CHECK_FOR_UPDATE, this);
		} else {
			UpdateHandler.this.errorMessage = activityForDB.getString(R.string.no_connection_error_message);
			updateHandlerListener.updateHandlerFailed(UpdateHandler.this);
		}
		
	}
	
	@Override
	public void onFailure(Throwable arg0) {
		UpdateHandler.this.errorMessage = "Exception: " + arg0.getMessage();
		updateHandlerListener.updateHandlerFailed(UpdateHandler.this);
	}

	@Override
	public void onSuccess(String responseStr) {
		// TODO Auto-generated method stub
		try {
			if (this.updateType == Constants.UPDATE_TYPE_CHECK_FOR_UPDATE) {
				JSONObject jsonObject = new JSONObject(responseStr);
				JSONObject response = jsonObject.optJSONObject(Constants.JSON_RESPONSE);
				
				if (response.has(Constants.JSON_LASTUPDATE_TIMESTAMP)) {
					long serverUpdateTimestamp = response.optLong(Constants.JSON_LASTUPDATE_TIMESTAMP);
					boolean needUpdate = serverUpdateTimestamp > ApplicationConf.getLongForKey(ApplicationConf.APPCONF_KEY_LASTUPDATE_TIMESTAMP);
					updateHandlerListener.needUpdate(needUpdate);
				} else {
					UpdateHandler.this.errorMessage = "Response: " + responseStr;
					updateHandlerListener.updateHandlerFailed(UpdateHandler.this);
				}
			} else if (this.updateType == Constants.UPDATE_TYPE_UPDATE) {
				if (this.updateState == Constants.UPDATE_STATE_CHECK_FOR_UPDATE) {
					JSONObject jsonObject = new JSONObject(responseStr);
					JSONObject response = jsonObject.optJSONObject(Constants.JSON_RESPONSE);
					
					if (response.has(Constants.JSON_LASTUPDATE_TIMESTAMP)) {
						serverLastUpdateTimestamp = response.optLong(Constants.JSON_LASTUPDATE_TIMESTAMP);
						boolean needUpdate = serverLastUpdateTimestamp > ApplicationConf.getLongForKey(ApplicationConf.APPCONF_KEY_LASTUPDATE_TIMESTAMP);
						if (needUpdate) {
							
							this.updateHandlerListener.updateIsInProgress(activityForDB.getString(R.string.updating_stores));
							this.updateState = Constants.UPDATE_STATE_POI_UPDATE;
							AsyncHttpClient client = new AsyncHttpClient();
							client.get(Constants.URL_BASE + Constants.URL_SUFFIX_UPDATE_POI + ApplicationConf.getLongForKey(ApplicationConf.APPCONF_KEY_LASTUPDATE_TIMESTAMP), this);
						} else {
							this.updateResultMessage = activityForDB.getString(R.string.client_is_uptodate);
							updateHandlerListener.updateHandlerDone(this);
						}
						
					} else {
						
						this.errorMessage = "Response: " + responseStr;
						updateHandlerListener.updateHandlerFailed(UpdateHandler.this);
					}
				} else if (this.updateState == Constants.UPDATE_STATE_POI_UPDATE) {
					Log.i(LOG_TAG, responseStr);
					JSONProcessor jsonProcessor = new JSONProcessor(Constants.JSONTYPE_POI, activityForDB, this);
					jsonProcessor.execute(responseStr);
				} else if (this.updateState == Constants.UPDATE_STATE_DRESS_UPDATE) {
					Log.i(LOG_TAG, responseStr);
					JSONProcessor jsonProcessor = new JSONProcessor(Constants.JSONTYPE_DRESS, activityForDB, this);
					jsonProcessor.execute(responseStr);
				}
			}
			
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			UpdateHandler.this.errorMessage = "Exception: " + e.getMessage();
			updateHandlerListener.updateHandlerFailed(UpdateHandler.this);
		}
	}
	
	@Override
	public void jsonProcessDone() {
		if (this.updateState == Constants.UPDATE_STATE_POI_UPDATE) {
			this.updateHandlerListener.updateIsInProgress(activityForDB.getString(R.string.updating_dresses));
			this.updateState = Constants.UPDATE_STATE_DRESS_UPDATE;
			AsyncHttpClient client = new AsyncHttpClient();
			client.get(Constants.URL_BASE + Constants.URL_SUFFIX_UPDATE_DRESS + ApplicationConf.getLongForKey(ApplicationConf.APPCONF_KEY_LASTUPDATE_TIMESTAMP), this);
		} else if (this.updateState == Constants.UPDATE_STATE_DRESS_UPDATE) {
			//TESZT - UNCOMMENT
			ApplicationConf.setLongForKey(ApplicationConf.APPCONF_KEY_LASTUPDATE_TIMESTAMP, serverLastUpdateTimestamp);
			this.updateResultMessage = activityForDB.getString(R.string.update_done);
			updateHandlerListener.updateHandlerDone(this);
		}
		
	}

	@Override
	public void jsonProcessFailed(String errorMessage) {
		this.errorMessage = errorMessage;
		this.updateHandlerListener.updateHandlerFailed(this);
	}
	
	public String getErrorMessage() {
		return errorMessage;
	}

	public void setErrorMessage(String errorMessage) {
		this.errorMessage = errorMessage;
	}
	
	public int getUpdateType() {
		return updateType;
	}

	public void setUpdateType(int updateType) {
		this.updateType = updateType;
	}

	

	public String getUpdateResultMessage() {
		return updateResultMessage;
	}

	public void setUpdateResultMessage(String updateResultMessage) {
		this.updateResultMessage = updateResultMessage;
	}
	
}
